/*
 Taylor Seale
 Computer Networks - Project 1
 
 TCP client portion of Project 1
 */

#include <stdio.h>		//printf
#include <string.h>		//memset
#include <stdlib.h>		//for exit(0);
#include <sys/socket.h>
#include <errno.h>		//For errno - the error number
#include <netdb.h>		//hostent
#include <arpa/inet.h>
#include <unistd.h>		//for read and write ?

//for reading temps
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <strings.h>

//for timestamp
#include <sys/time.h>
#include <time.h>


#define BUF_LEN 3200

struct client_data
{
	char host_name[32];
	int num_therms;
	int sensor_num;
	double sensor_data;
	double low_val;
	double high_val;
	char timestamp[32];
	int action;
};

struct packet
{
	unsigned char measurements;
	unsigned char counter;
	int16_t measurement0;
	int16_t measurement1;
	int16_t measurement2; 
};

/* Function to convert Celsius to Fahrenheit*/
float CtoF(float C){return (C*9.0/5.0)+32;}

char *hostname_to_ip (char *);

int main (int argc, char **argv)
{
	// establish necessary variables here
	int sockfd, n;		// socket and received buffer length
	
	if (argc != 3)
    {
		printf ("Incorrect Arguments!\n");
		printf ("usage: client <host> <port>\n");
		exit (1);
    }
	
	if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
    {
		printf ("Error creating socket\n");
		exit (1);
    }
	
	// to convert host name (returns original IP or hostname converted to IP)
	char *host = hostname_to_ip (argv[1]);
	
	// set up all the network stuff
	struct sockaddr_in servaddr;
	bzero (&servaddr, sizeof (servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_addr.s_addr = inet_addr (host);
	servaddr.sin_port = htons (atoi (argv[2]));
	
	if (connect (sockfd, (struct sockaddr *) &servaddr, sizeof (servaddr)) ==
		-1)
    {
		printf ("Error creating a connection with the server\n");
		exit (1);
    }
	
	//read the conf file//
	FILE * fp;
	char line[10];
	int numSensors=0;
	double sensorOneLow=0;
	double sensorOneHigh=0;
	double sensorTwoLow=0;
	double sensorTwoHigh=0;
	fp = fopen ("/etc/t_client/client.conf", "rt"); //open file for reading
	int pass=0;
	while (fgets(line,10,fp) != NULL)
	{
		//printf("LINE: %s\n", line);
		if (pass == 0)
		{
			numSensors=atoi(line);
		}
		if (pass == 1)
		{
			char * pch;
			pch = strtok (line, " ");
			int temp2=0;
			while (pch != NULL)
			{
				if (temp2==0)
				{
					sensorOneLow=atof(pch);
				}
				else
				{
					sensorOneHigh=atof(pch);
				}
				pch = strtok(NULL, " ");
				temp2++;
			}
		}
		//not sure why this is three?? but it works??
		if (pass == 3)
		{
			//printf ("LINE temp 2: %s\n",line);
			char * pch2;
			pch2 = strtok (line, " ");
			int temp2=0;
			while (pch2 != NULL)
			{
				if (temp2==0)
				{
					sensorTwoLow=atof(pch2);
				}
				else
				{
					sensorTwoHigh=atof(pch2);
				}
				//printf("TEST: %s\n",pch2);
				pch2 = strtok(NULL, " ");
				temp2++;
			}
		}
		pass++;
	}
	
	// print info to ensure it is correct
	printf("Num Sensors: %d\n",numSensors);
	printf("Sensor1 Low: %f\n",sensorOneLow);
	printf("Sensor1 High: %f\n",sensorOneHigh);
	printf("Sensor2 Low: %f\n",sensorTwoLow);
	printf("Sensor2 High: %f\n",sensorTwoHigh);
	
	
	//get the current value of sensors
	
	char *fileName="/dev/gotemp";
	char *fileName2="/dev/gotemp2";
	struct stat buf, buf2;
	struct packet temp, temp2;
	
	float conversion=0.0078125;
	int fd, fd2;
	
	if(stat( fileName, &buf ))
	{
	   if(mknod(fileName,S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP |S_IWGRP|S_IROTH|S_IWOTH,makedev(180,176)))
	   {
	      fprintf(stderr,"Cannot creat device %s  need to be root",fileName);
	/*      return 1; */
	   }
	}
	
	if(stat( fileName2, &buf2 ))
	{
	   if(mknod(fileName2,S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP |S_IWGRP|S_IROTH|S_IWOTH,makedev(180,177)))
	   {
	      fprintf(stderr,"Cannot creat device %s  need to be root",fileName2);
	/*      return 1; */
	   }
	}
	
	/* If cannot open, check permissions on dev, and see if it is plugged in */
	
	if((fd=open(fileName,O_RDONLY))==-1)
	{
	   fprintf(stderr,"Could not read %s\n",fileName);
	/*    return 1; */
	}
	if((fd2=open(fileName2,O_RDONLY))==-1)
	{
	   fprintf(stderr,"Could not read %s\n",fileName2);
	/*    return 1; */
	}
	
	/* if cannot read, check is it plugged in */
	
	if(read(fd,&temp,sizeof(temp))!=8)
	{
	   fprintf(stderr,"Error reading %s\n",fileName);
	/*    return 1; */
	}
	
	if(read(fd2,&temp2,sizeof(temp))!=8)
	{
	   fprintf(stderr,"Error reading %s\n",fileName2);
	/*    return 1; */
	}
	
	close(fd);
	close(fd2);
	
	double sensorOneTemp;
	double sensorTwoTemp;
	sensorOneTemp=CtoF(((float)temp.measurement0)*conversion);
	sensorTwoTemp=CtoF(((float)temp2.measurement0)*conversion);
	
	//print sensor temps
	printf("Sensor 1 Temp: %3.2f\nSensor 2 Temp: %3.2f\n",sensorOneTemp,sensorTwoTemp);
	     
	//get timestamp
	char *timestamp = (char *)malloc(sizeof(char)*32);
	memset(&timestamp[0],0,sizeof(timestamp));
	time_t ltime;
	ltime=time(NULL);
	struct tm *tm;
	tm=localtime(&ltime);
	//get ms
	struct timeval tv;
	gettimeofday(&tv,NULL);
	
	sprintf(timestamp,"%02d:%02d:%02d.%06d\n", tm->tm_hour,tm->tm_min, tm->tm_sec,(int)tv.tv_usec);

	//print timestamp
	printf("Timestamp: %s\n",timestamp);
	
	
	//transfer sensor data
	if (numSensors<1)
	{
		printf ("Error: Number of Sensors should be greater than 1\n");
	}
	
	struct client_data sensorOne;
	bzero(&sensorOne,sizeof(sensorOne));
	strncpy(sensorOne.host_name,"fun host", sizeof(sensorOne.host_name));
	sensorOne.num_therms=numSensors;
	sensorOne.sensor_num=1;
	sensorOne.sensor_data=sensorOneTemp;
	sensorOne.low_val=sensorOneLow;
	sensorOne.high_val=sensorOneHigh;
	strncpy(sensorOne.timestamp,timestamp, sizeof(sensorOne.timestamp));
	sensorOne.action=0;
	
	n=write(sockfd, (struct client_data*)&sensorOne, sizeof (sensorOne));
	printf("Sensor 1 Send Complete... Bytes Sent: %d\n",n);

	if (numSensors > 1)
	{
		struct client_data sensorTwo;
		bzero(&sensorTwo,sizeof(sensorTwo));
		strncpy(sensorTwo.host_name,"fun host", sizeof(sensorTwo.host_name));
		sensorTwo.num_therms=numSensors;
		sensorTwo.sensor_num=2;
		sensorTwo.sensor_data=sensorTwoTemp;
		sensorTwo.low_val=sensorTwoLow;
		sensorTwo.high_val=sensorTwoHigh;
		strncpy(sensorTwo.timestamp,timestamp, sizeof(sensorTwo.timestamp));
		sensorOne.action=0;
		
		n=write(sockfd, (struct client_data*)&sensorTwo, sizeof (sensorTwo));
		printf("Sensor 2 Send Complete... Bytes Sent: %d\n",n);
	}
	
	close (sockfd);
	return 0;
}


// if a hostname is given, convert it to an IP address
// if an IP address is given, that IP address is returned
char * hostname_to_ip (char *host)
{
	struct hostent *h;
	h = gethostbyname (host);
	host = inet_ntoa (*((struct in_addr *) h->h_addr));
	return host;
}
